
#include <iostream>
#include <unistd.h>
#include <memory>
#include <fstream>

#include "TcpServer.hpp"
#include "HttpProtocol.hpp"

using namespace std;
using namespace Network;

string SuffixToContentType(const string &suffix)
{
    if (suffix == ".html")
        return "text/html";
    else if (suffix == ".png")
        return "image/png";
    else if (suffix == ".jpg")
        return "image/jpeg";
    else
        return "text/html";
}

string CodetoDesc(int code)
{
    switch (code)
    {
    case 200:
        return "OK";
    case 301:
        return "Moved Permanently";
    case 307:
        return "Temporary Redirect";
    case 403:
        return "Forbidden";
    case 404:
        return "Not Found";
    case 500:
        return "Internal Server Error";
    case 503:
        return "Service Unavailable";
    default:
        return "Unknown";
    }
}

// 网络负责IO发送
// HandlerHttpRequest字节流数据解析和调用业务处理方法
// 处理报文的方法
// 我们认为我们已经读到了一个完整请求
string HandlerHttpRequest(string &request)
{

    HttpRequest req;

    // 反序列化
    req.Deserialize(request);

    // 解析URL
    req.Parse();
    req.Debug();

    string content;
    content = req.GetFileContent();//获取文件内容

    // 业务处理
    // 我们假设业务处理成功
    int code = 200;

    if (content.empty())
    {
        // 找不到文件
        code = 404;
        content = req.Get_404();
    }

    // 构建响应
    HttpResponse resp;
    resp.SetCode(code);// 设置状态码
    resp.SetVersion(req.GetVersion());// 设置版本
    resp.SetDesc(CodetoDesc(code));// 设置描述
    
    resp.MakeStatusLine();//构建转换为字符串的状态行
    
    string content_len_str = "Content-Length: " + to_string(content.size()) ;// 正文长度
    resp.AddHeader(content_len_str);

    string content_type_str = "Content-Type: " + SuffixToContentType(req.GetSuffix()) ; // 正文类型
    resp.AddHeader(content_type_str);

    string namecookie="Set-Cookie:username=zhangsan";//设置cookie
    resp.AddHeader(namecookie);

    string passwdcookie="Set-Cookie:password=123456";//设置cookie
    resp.AddHeader(passwdcookie);

    string statuscookie="Set-Cookie:status=logined";//设置cookie
    resp.AddHeader(statuscookie);

    // string localtion="Location: http://www.baidu.com";
    // resp.AddHeader(localtion);
    resp.AddContent(content);
    return resp.Serialize(); // 序列化
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        cout << "Usage:\n     ./udp_echo_server <port>" << endl;
        return 0;
    }

    uint16_t localport = stoi(argv[1]);

    unique_ptr<TcpServer> svr(new TcpServer(localport, HandlerHttpRequest));
    svr->Loop();
    return 0;
}
